package android.framework.binding;

import java.util.ArrayList;
import java.util.List;

import android.framework.binding.converters.ConverterHelper;
import android.framework.binding.converters.IConverter;


public class Binding {
	private static long actionId = 0;
	
	public static synchronized long getNextActionId(){
		return actionId++;
	}
	
	public static <T> void attached(IBindable<T> ... bindables ){
		List<IObserver<T>> observers = new ArrayList<IObserver<T>>();
		for (IBindable<T> iBindable : bindables) {
			 observers.add(iBindable);
		}
		
		for (IBindable<T> iBindable : bindables) {
			List<IObserver<T>> listWithoutCurrent = new ArrayList<IObserver<T>>(observers);
			listWithoutCurrent.remove(iBindable);
			iBindable.setListener(new MultiBindingAdapter<T>(listWithoutCurrent));
		}
	}
	
	public static <T> void attached(IBindable<T> first, IBindable<T> second){
		first.clearListeners();
		first.addListener(second);
		
		second.clearListeners();
		second.addListener(first);
		
		second.notifyChanges(first.getLastValue(), getNextActionId());
	}
	
	public static <T> void attached(IBindableList<T> first, IBindableList<T> second){
		//TODO:: add support to clearListener, like on regular attached 
		//first.clearListeners();
		//second.clearListeners();
		
		first.addListener(second);
		second.addListener(first);
	}
	
	public static <T,G> void attached(IBindable<T> first, IBindable<G> second, IConverter<T, G> converter){
		IBindingAdapter<T, G> firstAdapter = new BindingAdapter<T, G>(first, converter);
		IBindingAdapter<G, T> secondsAdapter = new BindingAdapter<G, T>(second, ConverterHelper.getOposite(converter));
		
		first.clearListeners();
		second.clearListeners();
		
		first.addListener(firstAdapter);
		firstAdapter.addListener(second);
		second.addListener(secondsAdapter);
		secondsAdapter.addListener(first);
		
		firstAdapter.notifyChanges(first.getLastValue(), getNextActionId());
	}
	
}
